1 /** 2 * Declared the majority of the interfaces for Devisualization.Window 3 * 4 * Authors: 5 * Richard Andrew Cattermole 6 * 7 * License: 8 * The MIT License (MIT) 9 * 10 * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole) 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a copy 13 * of this software and associated documentation files (the "Software"), to deal 14 * in the Software without restriction, including without limitation the rights 15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 * copies of the Software, and to permit persons to whom the Software is 17 * furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be included in all 20 * copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 * SOFTWARE. 29 * 30 * Examples: 31 * To create a window without an OpenGL context: 32 * --- 33 * Windowable window = new Window(800, 600, "My window!"w, 100, 100); 34 * window.show(); 35 * Window.messageLoop(); 36 * --- 37 * 38 * This runs the message loop after showing the window. 39 * Does nothing with events. Or show any content. 40 */ 41 module devisualization.window.interfaces.window; 42 import devisualization.window.interfaces.eventable; 43 public import devisualization.window.interfaces.events; 44 import devisualization.window.interfaces.context; 45 46 /** 47 * Arguments to create a window. 48 * Some may be optional. 49 * 50 * A minimum width and height should be supplied. 51 * 52 * See_Also: 53 * Windowable 54 */ 55 struct WindowConfig { 56 /** 57 * Width of the window to create. 58 * Must be atleast 0 (px). 59 */ 60 uint width; 61 62 /** 63 * Height of the window to create. 64 * Must be atleast 0 (px). 65 */ 66 uint height; 67 68 /** 69 * The title of the window to create. 70 * Commonly a UTF-8 support should be available. 71 * However if not ASCII will be used. Which is effectively a string. 72 * Assume ASCII values are safe as a value. 73 * 74 * Default: 75 * "A DWC window" 76 */ 77 wstring title = "A DWC window"; 78 79 /** 80 * The x position of the window to be created. 81 * It is possible that this is ignored by the implementation. 82 * 83 * Default: 84 * 0 (px) 85 */ 86 int x; 87 88 /** 89 * The y position of the window to be created. 90 * It is possible that this is ignored by the implementation. 91 * 92 * Default: 93 * 0 (px) 94 */ 95 int y; 96 97 /** 98 * Specifies the type of context to create. Validated by the window implementation. 99 * 100 * Default: 101 * None 102 */ 103 WindowContextType contextType; 104 105 /** 106 * Forces width and height to be atleast 0 (px). 107 */ 108 invariant() { 109 assert(width > 0, "Should a window really have a 0px width?"); 110 assert(height > 0, "Should a window really have a 0px height?"); 111 } 112 } 113 114 /** 115 * A generic window interface. 116 * 117 * Should be supportive of majority of windowing toolkits in existance. 118 * Is unaware of screens. 119 * 120 * Implementation should support two constructors: 121 * --- 122 * this(T...)(T config) { this(WindowConfig(config)); } 123 * this(WindowConfig config); 124 * --- 125 * 126 * Events_Mechanism: 127 * A window support a set number of events. 128 * From those the event offer set functionality to manipulate them. 129 * 130 * Adds a listener on an event 131 * --- 132 * void addEventName(void delegate(T)); 133 * void addEventName(bool delegate(T)); 134 * --- 135 * 136 * Removes the provided listener 137 * --- 138 * void removeEventName(bool delegate(T)); 139 * void removeEventName(void delegate(T)); 140 * --- 141 * 142 * Counts how many listeners for an event 143 * --- 144 * size_t countEventName(); 145 * --- 146 * 147 * Runs the event for all listeners with the given arguments 148 * --- 149 * void eventName(T); 150 * --- 151 * 152 * Clears all listeners for an event 153 * --- 154 * void clearEventName(); 155 * --- 156 * 157 * Optionally will also support: 158 * --- 159 * void eventName(T[1 .. $]); 160 * --- 161 * Where T[0] is Windowable. 162 * This will run the event and pass in as first argument this (Windowable). 163 * 164 * Events: 165 * Upon the message loop drawing period this is called.<br/> 166 * onDraw = Windowable 167 * 168 * When the message loop is informed the window has moved, this is called.<br/> 169 * onMove = Windowable, int x, int y 170 * 171 * When the message loop is informed the window has resized, this is called.<br/> 172 * onResize = Windowable, uint newWidth, uint newHeight 173 * 174 * When the window has been requested to be closed from the user, this is called.<br/> 175 * On this event Windowable.close must be called manually.<br/> 176 * onClose = Windowable 177 */ 178 interface Windowable { 179 import devisualization.image; 180 181 //this(T...)(T config) { this(WindowConfig(config)); } 182 //this(WindowConfig); 183 184 static { 185 /** 186 * Continues iteration of the message loop. 187 * 188 * This is expected functionality provided from the implementation. 189 */ 190 void messageLoop(); 191 192 /** 193 * A single iteration of the message loop. 194 * 195 * This is expected functionality provided from the implementation. 196 */ 197 void messageLoopIteration(); 198 } 199 200 /** 201 * Hides the window. 202 * 203 * See_Also: 204 * hide 205 */ 206 void show(); 207 208 /** 209 * Shows the window. 210 * 211 * See_Also: 212 * close 213 */ 214 void hide(); 215 216 /* 217 * Window 218 */ 219 220 mixin IEventing!("onDraw", Windowable); 221 mixin IEventing!("onMove", Windowable, int, int); 222 mixin IEventing!("onResize", Windowable, uint, uint); 223 mixin IEventing!("onClose", Windowable); 224 225 /* 226 * Mouse 227 */ 228 229 mixin IEventing!("onMouseDown", Windowable, MouseButtons, int, int); 230 mixin IEventing!("onMouseMove", Windowable, int, int); 231 mixin IEventing!("onMouseUp", Windowable, MouseButtons); 232 233 /* 234 * Keyboard 235 * KeyModifiers is an or'd mask or modifiers upon the key 236 */ 237 238 mixin IEventing!("onKeyDown", Windowable, Keys, KeyModifiers); 239 mixin IEventing!("onKeyUp", Windowable, Keys, KeyModifiers); 240 241 @property { 242 243 /** 244 * Sets the title text. 245 * 246 * Params: 247 * text = The text to set the title of the window to 248 */ 249 void title(string text); 250 251 /** 252 * Sets the title text. 253 * 254 * Params: 255 * text = The text to set the title of the window to 256 */ 257 void title(dstring text); 258 259 /** 260 * Sets the title text. 261 * 262 * Params: 263 * text = The text to set the title of the window to 264 */ 265 void title(wstring text); 266 267 /** 268 * Resize the window. 269 * 270 * Does not animate. 271 * 272 * Params: 273 * width = The width to set to 274 * height = The height to set to 275 */ 276 void size(uint width, uint height); 277 278 /** 279 * Move the window to coordinate. 280 * 281 * Coordinate system based upon Top left corner of screen. 282 * Does not support screens (could be moved outside main screen). 283 * Coordinates can be negative, but is dependent upon the OS. 284 * 285 * Params: 286 * x = The x coordinate to move to 287 * y = The y coordinate to move to 288 */ 289 void move(int x, int y); 290 291 /** 292 * Enable / disable resizing of the window. 293 * 294 * Params: 295 * can = Is it possible to resize the window (default yes) 296 */ 297 void canResize(bool can = true); 298 299 /** 300 * Go into/out fullscreen 301 * 302 * Params: 303 * isFullscreen = Should be fullscreen (default yes) 304 */ 305 void fullscreen(bool isFullscreen = true); 306 307 /** 308 * Closes the window. 309 * The window cannot reopened once closed. 310 * 311 * See_Also: 312 * hide 313 */ 314 void close(); 315 316 /** 317 * Has the window been closed? 318 * 319 * Returns: 320 * True if close has been called 321 * 322 * See_Also: 323 * close 324 */ 325 bool hasBeenClosed(); 326 327 /** 328 * Gets the current context that the window has open or null for none. 329 * 330 * Returns: 331 * A context that has a buffer that can be swapped and activated once created 332 */ 333 IContext context(); 334 } 335 336 /** 337 * Sets the icon for the window. 338 * Supports transparency. 339 * 340 * Params: 341 * image = The image (from Devisualization.Image). 342 */ 343 void icon(Image image); 344 345 /** 346 * Sets the icon for the window. 347 * Supports transparency. 348 * 349 * Params: 350 * width = The width of the icon 351 * height = The height of the icon 352 * data = rgb data 0 .. 255, 3 bytes per pixel 353 * transparent = The given pixel (3 bytes like data) color to use as transparency 354 * 355 * Deprecated: 356 * Superseded by using Devisualization.Image's Image, as argument instead. 357 */ 358 deprecated("Use Devisualization.Image method instead") 359 void icon(ushort width, ushort height, ubyte[3][] data, ubyte[3]* transparent = null); 360 } 361 362 class WindowNotCreatable : Exception { 363 @safe pure nothrow this(string file = __FILE__, size_t line = __LINE__, Throwable next = null) { 364 super("Window failed to be created.", file, line, next); 365 } 366 367 @safe pure nothrow this(Throwable next, string file = __FILE__, size_t line = __LINE__) { 368 super("Window failed to be created.", file, line, next); 369 } 370 }